
<?php

/**
 * 编译类：将模板文件编译为php文件
 **/
class compile {

    // 文件内容
	private $content; 
	private $pattern = [
		'/{(if|foreach|for|while)(.*?)}/',
		'/{loop(.*?)}/',
		'/{(else if|elseif)(.*?)}/',
		'/{(else)}/',
		'/{(do while)}/',
		'/{\/(do while)(.*?)}/',
		'/{\/(foreach|if|for|while|do|loop)}/',
		'/{(continue|break)}/',
		'/{php}(.*?){\/php}/s',
		'/{php(.*?)}/',
		'/{(.*?)}/',
		'/##\^%(.*?)%\^##/'
	];
	private $translation = [
		'<?php \\1 (\\2 ) { ?>',
		'<?php foreach (\\1 ) { ?>',
		'<?php } else if (\\2 ) { ?>',
		'<?php } \\1 { ?>',
		'<?php do { ?>',
		'<?php } while (\\2 ) ?>',
		'<?php } ?>',
		'<?php \\1 ?>',
		'<?php \\1 ?>',
		'<?php \\1\\2 ?>',
		'<?php echo \\1; ?>',
		'{\\1}',
	];

	/**
	 * 将模板文件编译php文件
	 **/
	public function execute($tmpFile, $cmpFile, $dir_template, $suffix_tpl) {
		if(!($this->content = file_get_contents($tmpFile))){
			err::setError("文件读取失败：", $tmpFile);	
		}

		// 处理include文件包含
		$mode='/\{(include_once|require_once|include|require)\s+file=\"(.+)\"\}/'; //普通文件包含标签模式
		// $mode='/{(include_once|require_once|include|require)(.*?)}/'; //普通文件包含标签模式
		if (preg_match_all ( $mode, $this->content, $file )) {
			foreach($file[2] as $key => $val) {
				$include_file = null;
				if (!file_exists ( $dir_template . $val )) {
					err::setError('包含文件出错：', $dir_template . $val);
				} else {
					$include_file = file_get_contents($dir_template . $val);//加载包含文件的内容
					$this->content = preg_replace ( $mode, $include_file, $this->content, 1 ); //替换成相应的php语言中的include包含语句
				}
			}
		}

		// 处理不编译标签
		$this->content = preg_replace_callback(
			'/{literal}(.+?){\/literal}/s', function($matches) { return preg_replace('/{(.+?)}/', '##^%\\1%^##', $matches[1]); }, $this->content
		);
		//替换预置规则
		$this->content = preg_replace($this->pattern, $this->translation, $this->content);
		//处理输出标签
		$this->content = preg_replace_callback(
			'/\<\?(php|=)(.+?)\?>/s', function($matches) { return preg_replace('/\@([a-z0-9_]*)/', '$this->value["\\1"]', $matches[0]); }, $this->content
		);
		//写入文件
		$this->parse($cmpFile);
    }
	/**
	 * 将编译好的内容写入文件 
	 **/
	private function parse($cmpFile) {
		if(!file_put_contents($cmpFile, $this->content)){
			err::setError('文件写入失败：',$cmpFile);
		}
	}

	private function get_tag_data($html, $tag, $type = 1){
		$regex = ($type == 1) ? "/\{$tag(.*?)}/is" : "/\{$tag}(.*?){\/$tag}/is";
		preg_match_all($regex, $html, $matches, PREG_PATTERN_ORDER);
		return $matches[1];
	}
}
